structure T = Tokens

type lexresult = Tokens.token
type pos = int

val lineNum = ref 0
val linePos = ref [0]
  
val eof = (fn () => Tokens.EOF)

fun str2int str = let val result=Int.fromString str 
		     in 
			 case result of SOME i => i 
				      | NONE => 0
		     end 

%%
%posarg
%s COMMENT LCOMMENT;
letter=[_a-zA-Z];
al=[_0-9a-zA-Z];
digit=[0-9];
id=({letter})({letter}|{digit})*;
ws=[\ \t\r\n];
string=\".+\";
%%

<INITIAL>{ws}+ 	        => (continue());

<INITIAL>"->"           => (T.ARROW(yypos));
<INITIAL>"."           => (T.DOT(yypos));
<INITIAL>","           => (T.COMMA(yypos));
<INITIAL>";"           => (T.SEMICOLON(yypos));
<INITIAL>"("           => (T.LPAREN(yypos));
<INITIAL>")"           => (T.RPAREN(yypos));
<INITIAL>"["           => (T.LBRACK(yypos));
<INITIAL>"]"           => (T.RBRACK(yypos));
<INITIAL>"{"           => (T.LBRACE(yypos));
<INITIAL>"}"           => (T.RBRACE(yypos));
<INITIAL>"+"           => (T.PLUS(yypos));
<INITIAL>"-"           => (T.MINUS(yypos));
<INITIAL>"*"           => (T.TIMES(yypos));
<INITIAL>"/"           => (T.DIVIDE(yypos));
<INITIAL>"%"           => (T.MODUS(yypos));
<INITIAL>">="           => (T.GE(yypos));
<INITIAL>"<="           => (T.LE(yypos));
<INITIAL>">"           => (T.GT(yypos));
<INITIAL>"<"           => (T.LT(yypos));
<INITIAL>"=="           => (T.EQ(yypos));
<INITIAL>"!="           => (T.NEQ(yypos));
<INITIAL>"&&"           => (T.AND(yypos));
<INITIAL>"||"           => (T.OR(yypos));
<INITIAL>"!"           => (T.NOT(yypos));
<INITIAL>"="           => (T.ASSIGN(yypos));
<INITIAL>"enum"           => (T.ENUM(yypos));
<INITIAL>"int"           => (T.INT(yypos));
<INITIAL>"char"           => (T.CHAR(yypos));
<INITIAL>"void"           => (T.VOID(yypos));
<INITIAL>"if"           => (T.IF(yypos));
<INITIAL>"for"           => (T.FOR(yypos));
<INITIAL>"else"           => (T.ELSE(yypos));
<INITIAL>"while"           => (T.WHILE(yypos));
<INITIAL>"struct"           => (T.STRUCT(yypos));
<INITIAL>"return"           => (T.RETURN(yypos));


<INITIAL>"/*"		=> (YYBEGIN COMMENT; continue());
<INITIAL>"//"		=> (YYBEGIN LCOMMENT; continue());
<COMMENT>"*/"		=> (YYBEGIN INITIAL; continue());
<LCOMMENT>"\n"		=> (YYBEGIN INITIAL; lineNum := !lineNum+1; linePos := yypos :: !linePos; continue());
<COMMENT>"\n"		=> (lineNum := !lineNum+1; linePos := yypos :: !linePos; continue());
<COMMENT,LCOMMENT>.	=> (continue());


<INITIAL>{id}           => (T.ID(yytext,yypos));
<INITIAL>{digit}+	=> (T.INTCONST(yytext,yypos));
<INITIAL>{string}       => (T.STRINGCONST(yytext,yypos));
<INITIAL>.       	=> (print ("Invalid character: "^yytext^"\n"); continue());
